/********************************************************************
filename : wolf_adc.c
discript : dreamwolf ADC driver,the pinmap as bellow:
					 Analog out   -> ADC123_IN12(PC2).
version  : V0.0
version  : V0.0
editor   : Icy - dreamwolf
time     : 2014.4.28
statement: This file is modified by dreamwolf under LGPL,you could use 
           it free.We cann't ensure there is no error in this file,and
				   if you detect an error please contact us freely,it is so a-
					 ppreciate for your help to improve our code that could help 
					 more people to use it safty.
contact  : edreamtek@163.com
           www.edreamtek.com
********************************************************************/

#include "wolf_adc.h"


uint16_t Precent = 0, Voltage = 0;
ADC_RESULT ADC_result;
__IO uint16_t ADCConvertedValue;     	//ADC width is 12 bits,low 12 bits is data.
__IO uint16_t ADC1ConvertedValue = 0;
__IO uint32_t ADC1ConvertedVoltage = 0;

__IO uint32_t TempSensVoltmv = 0, VrefIntVoltmv = 0;
__IO uint16_t RegularConvData_Tab[3];


/********************************************************************
function: ADC1_CH_DMA_Config(void)
discript: Init port,DMA
entrance: none
return  : none
other   : none
********************************************************************/
void ADC1_CH_DMA_Config(void)
{
  ADC_InitTypeDef     ADC_InitStructure;
  DMA_InitTypeDef     DMA_InitStructure;
  
  /* ADC1 DeInit */  
  ADC_DeInit(ADC1);
  
  /* ADC1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
  
  /* DMA1 Channel1 Config */
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 3;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
  /* DMA1 Channel1 enable */
  DMA_Cmd(DMA1_Channel1, ENABLE);
  
  /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  
  /* Enable ADC_DMA */
  ADC_DMACmd(ADC1, ENABLE);  
  
  /* Initialize ADC structure */
  ADC_StructInit(&ADC_InitStructure);
  
  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
  ADC_Init(ADC1, &ADC_InitStructure); 
 
  /* Convert the ADC1 Channel1  with 55.5 Cycles as sampling time */ 
  ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_55_5Cycles); 
  ADC_VrefintCmd(ENABLE);

	/* Convert the ADC1 temperature sensor  with 55.5 Cycles as sampling time */ 
  ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  
  ADC_TempSensorCmd(ENABLE);
  
  /* Convert the ADC1 Vref  with 55.5 Cycles as sampling time */ 
  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles); 
  ADC_VrefintCmd(ENABLE);

  /* ADC Calibration */
  ADC_GetCalibrationFactor(ADC1);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);     
  
  /* Wait the ADCEN falg */
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); 
  
  /* ADC1 regular Software Start Conv */ 
  ADC_StartOfConversion(ADC1);
}


/********************************************************************
function: wolf_read_ADC_result(void)
discript: 
entrance: none
return  : Result of ADC
other   : ADC result will be save to RegularConvData_Tab,ADC Channel1
					first,VrefIntVoltmv last,see more sequence at stm32f0xx_adc.h.
********************************************************************/
ADC_RESULT wolf_read_ADC_result(void)
{
	/* Test DMA1 TC flag */
	while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET ){}; 
    
  /* Clear DMA TC flag */
  DMA_ClearFlag(DMA1_FLAG_TC1);
    
  /* Convert temperature sensor voltage value in mv */
  TempSensVoltmv = (uint32_t)((RegularConvData_Tab[1]* 3300) / 0xFFF);
    
  /* Convert Vref voltage value in mv */
  VrefIntVoltmv  = (uint32_t)((RegularConvData_Tab[2]* 3300) / 0xFFF);  
		
	Precent = (RegularConvData_Tab[0]*100/0xFFF);		//Caculate precent
  Voltage = Precent*33;						  							//Caculate voltage with reference voltage.
	ADC_result.ADCConvertedValueLocal = RegularConvData_Tab[0];
	ADC_result.Precent = Precent;
	ADC_result.Voltage = Voltage;

	return ADC_result;
}

